import QtQuick 2.0
import SignalConnection 1.0
import Decimator 1.0
import Splitter 1.0
import SmartingEEGClientAgent 1.0
import SmartingEEGRecord 1.0
import CustomPlot 1.0
import NotchFilter 1.0
import ButterFilter 1.0
import SmartingImpedanceMeter 1.0

Flickable{
    property var decimatorList: []
    property var splitterList1: []
    property var lowFilterList: []
    property var highFilterList: []
    property var notchFilterList: []
    property var splitterList2: []

    property int numOfSignals : 28
    property int visibleGraphs : 28
    property int displayedGraphs : 3
    property var recordDir: "/sdcard";
    property var recordDescText: settingsView.recordDescText

    function newRecord()
    {
        eegRecord.newRecord(recordDir, recordDescText);
    }

    function closeRecord()
    {
        eegRecord.closeRecord();
    }

    width: parent.width
    height: parent.height
    contentWidth:  width
    contentHeight: (height/displayedGraphs)*numOfSignals
    interactive:true
    clip:true
    boundsBehavior: Flickable.StopAtBounds
    flickableDirection:Flickable.VerticalFlick

    SmartingEEGRecord
    {
        id: eegRecord
    }

    SignalConnection
    {
        id: signalConnection
    }

    Column
    {
        width: plotView.width
        height: plotView.height

        Repeater
        {
            id: plotList
            model: numOfSignals
            Plot
            {
                id: channel
                objectName: "channel"
                width: parent.width
                height: parent.height/displayedGraphs
                signalDuration : 5.0
                signalActive: false

                SmartingImpedanceMeter
                {
                    id: impedance
                    objectName: "impedance"
                    width: parent.width * 0.1
                    visible: (index < 4)? false : parent.visible
                }
            }
        }
    }

    onMovementEnded: updatePlotRefreshing()

    function updatePlotRefreshing()
    {
        var screenStart =  contentY;
        var screenEnd  =  contentY + plotView.height;
        var graphHeight = plotList.itemAt(0).height;
        var graphTop;
        var graphBottom = 0;

        if(eegAgent.isBufferOverloaded())
        {
            for(var i = 0 ; i < plotList.count; i++)
            {
                plotList.itemAt(i).signalActive = false;
            }
        }else
        {
            for(var i = 0 ; i < plotList.count; i++)
            {
                if(plotList.itemAt(i).visible)
                {
                    graphTop = graphBottom;
                    graphBottom = graphTop + graphHeight;

                    if ((screenStart < graphBottom) && (graphTop < screenEnd))
                    {
                        plotList.itemAt(i).signalActive = true;
                    }
                    else
                    {
                        plotList.itemAt(i).signalActive = false;
                    }
                }
            }
        }
    }

    function visibilityChanged(index,value)
    {
        plotList.itemAt(index).visible = !plotList.itemAt(index).visible;

        if(value){
            plotView.contentHeight = plotView.contentHeight + plotList.itemAt(index).height;
            visibleGraphs+=1;
        }
        else{
            plotView.contentHeight = plotView.contentHeight - plotList.itemAt(index).height;
            visibleGraphs-=1;

        }
    }

    function isVisible(index)
    {
        return plotList.itemAt(index).visible;
    }

    function plotSettingsChanged(duration,numOfGraphs)
    {
        for(var i = 0 ; i < numOfSignals; i++)
        {
            plotList.itemAt(i).signalDuration = duration;   
            plotList.itemAt(i).height = plotView.height/numOfGraphs;
        }
        plotView.contentHeight = plotView.height*visibleGraphs/numOfGraphs;
    }

    function filterSettingsChanged(lowpass,highpass,notch)
    {
        for(var i = 0; i < numOfSignals; ++i)
        {
            lowFilterList[i].setCoefficients(lowpass/500,ButterFilter.LOWPASS);
            highFilterList[i].setCoefficients(highpass/500,ButterFilter.HIGHPASS);
            notchFilterList[i].setCoefficients(notch/500,0.01);
        }
    }

    Component.onCompleted:
    {
        var burstLength = 50;

        for(var i = 0 ; i< numOfSignals; i++)
        {
            plotList.itemAt(i).init();
            if(i > 3)
            {
                plotList.itemAt(i).children[0].init(burstLength);
            }
        }

        for(var i = 0 ; i < displayedGraphs ; i++)
        {
            plotList.itemAt(i).signalActive = true;
        }
        plotList.itemAt(0).name = "Sync Channel ";
        plotList.itemAt(1).name = "Gyroscope X  ";
        plotList.itemAt(2).name = "Gyroscope Y  ";
        plotList.itemAt(3).name = "Gyroscope Z  ";

        for(var i = 4; i < numOfSignals ; i++){
            plotList.itemAt(i).name = "Ch "+(i-3) + "   ";
        }

        // create objects
        for(var i = 0; i < numOfSignals; ++i)
        {
            splitterList1.push(Qt.createQmlObject("import Splitter 1.0; Splitter {}", this));

            decimatorList.push(Qt.createQmlObject("import Decimator 1.0; Decimator {}", this));
            splitterList2.push(Qt.createQmlObject("import Splitter 1.0; Splitter {}", this));

            lowFilterList.push(Qt.createQmlObject("import ButterFilter 1.0; ButterFilter {}", this));
            highFilterList.push(Qt.createQmlObject("import ButterFilter 1.0; ButterFilter {}", this));
            notchFilterList.push(Qt.createQmlObject("import NotchFilter 1.0; NotchFilter {}", this));
        }

        //batteryValue = 0;

        // init objects
        eegRecord.init(burstLength);
        for(var i = 0; i < numOfSignals; ++i)
        {
            splitterList1[i].init(burstLength);

            decimatorList[i].init(10, burstLength);
            splitterList2[i].init(burstLength);

            lowFilterList[i].init(10,burstLength);
            lowFilterList[i].setCoefficients(70/500,ButterFilter.LOWPASS);

            highFilterList[i].init(10,burstLength);
            highFilterList[i].setCoefficients(10/500,ButterFilter.HIGHPASS);

            notchFilterList[i].init(burstLength);
            notchFilterList[i].setCoefficients(50/500,0.01);
        }

        // connect objects
        signalConnection.connect(eegAgent.getSyncOSignal(), splitterList1[0].getISignal());
        signalConnection.connect(splitterList1[0].getMasterOSignal(), decimatorList[0].getISignal());
        signalConnection.connect(decimatorList[0].getOSignal(), plotList.itemAt(0).getISignal());
        signalConnection.connect(splitterList1[0].getSlaveOSignal(), eegRecord.getSyncISignal());

        signalConnection.connect(eegAgent.getGyroXOSignal(), splitterList1[1].getISignal());
        signalConnection.connect(splitterList1[1].getMasterOSignal(), decimatorList[1].getISignal());
        signalConnection.connect(decimatorList[1].getOSignal(), plotList.itemAt(1).getISignal());
        signalConnection.connect(splitterList1[1].getSlaveOSignal(), eegRecord.getGyroXISignal());

        signalConnection.connect(eegAgent.getGyroYOSignal(), splitterList1[2].getISignal());
        signalConnection.connect(splitterList1[2].getMasterOSignal(), decimatorList[2].getISignal());
        signalConnection.connect(decimatorList[2].getOSignal(), plotList.itemAt(2).getISignal());
        signalConnection.connect(splitterList1[2].getSlaveOSignal(), eegRecord.getGyroYISignal());

        signalConnection.connect(eegAgent.getGyroZOSignal(), splitterList1[3].getISignal());
        signalConnection.connect(splitterList1[3].getMasterOSignal(), decimatorList[3].getISignal());
        signalConnection.connect(decimatorList[3].getOSignal(), plotList.itemAt(3).getISignal());
        signalConnection.connect(splitterList1[3].getSlaveOSignal(), eegRecord.getGyroZISignal());

        signalConnection.connect(eegAgent.getBatteryOSignal(), eegRecord.getBatteryISignal());

        for(var i = 0; i < numOfSignals-4; ++i)
        {
            signalConnection.connect(eval("eegAgent.getChannel" + i + "OSignal()"), splitterList1[i+4].getISignal());
            signalConnection.connect(splitterList1[i+4].getMasterOSignal(), splitterList2[i+4].getISignal());
            signalConnection.connect(splitterList1[i+4].getSlaveOSignal(), plotList.itemAt(i+4).children[0].getISignal());

            signalConnection.connect(splitterList2[i+4].getMasterOSignal(),lowFilterList[i].getISignal());
            signalConnection.connect(lowFilterList[i].getOSignal(),highFilterList[i].getISignal());
            signalConnection.connect(highFilterList[i].getOSignal(),notchFilterList[i].getISignal());
            signalConnection.connect(notchFilterList[i].getOSignal(),decimatorList[i+4].getISignal());
            signalConnection.connect(decimatorList[i+4].getOSignal(), plotList.itemAt(i+4).getISignal());

            signalConnection.connect(splitterList2[i+4].getSlaveOSignal(), eval("eegRecord.getChannel" + i + "ISignal()"));
        }

        // start objects
        eegRecord.start();
        for(var i = 0; i < numOfSignals; ++i)
        {
            plotList.itemAt(i).start();
            if(i > 3)
            {
                plotList.itemAt(i).children[0].start();
            }
        }
    }
}
